<?php
namespace App\Lib\Amqp\Message;

use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;
use Swoft\Bean\Annotation\Mapping\Bean;

/**
 * RabbitMQ Message
 * Class Message
 * @package App\Lib\Amqp\Message
 * @Bean("MQMessage")
 */
class Message extends AbstractMessage
{

    /**
     * 初始化 Message
     * @param null $msg
     * @return mixed|void
     */
    public function initMessage($msg = null): Message
    {
        $Message = clone $this;

        if ($msg instanceof AMQPMessage) {
            // 如果传递的 msg 参数是 AMQPMessage 对象
            $Message->setSourceData($msg);
            $body = $msg->body;
            $Message->setBody($body);
            $formatBody = json_decode($body, true);
            if (is_array($formatBody)) {
                $Message = $Message->initByArray($formatBody);
            } else {
                $Message->setContent($body);
            }
            // 如果是获取到的 msg 应该设置 channel 用来ack消息使用
            $channel = $msg->delivery_info['channel'] ?? null;
            if ($channel && ($channel instanceof AMQPChannel)) {
                $Message->setChannel($channel);
            }
            $deliveryTag = $msg->delivery_info['delivery_tag'] ?? null;
            if (is_int($deliveryTag)) {
                $Message->setDeliveryTag($deliveryTag);
            }
            return $Message;
        } else if (is_array($msg)) {
            // 如果传递的是数组
            return $Message->initByArray($msg, true);
        } else if (is_string($msg))
        {
            if($msg = json_decode($msg, true))
            {
                // 传递的是 JSON 默认字符串是content 内容体
                $Message->setContent($msg);
                return $Message;
            }
        } else {
            // 啥也不是 直接返回一个空的 消息对象 自己去搞
            return $Message;
        }
    }

    /**
     * 使用数组信息初始化 Message对象
     * @param array $msg
     * @param bool $setDefault
     * @return $this
     */
    private function initByArray (array $msg, bool $setDefault = false)
    {
        // 初始化 tenant
        $tenant = $msg['tenant'] ?? '';
        if (empty($tenant) && $setDefault) {
            $this->createDefaultTenant();
        } else {
            $this->setTenant($tenant);
        }

        // 初始化 UUID
        $UUID = $msg['id'] ?? '';
        if (empty($UUID) && $setDefault) {
            $this->createDefaultUUID();
        } else {
            $this->setID($UUID);
        }

        // 初始化 title
        $title = $msg['title'] ?? '';
        if (! empty($title)) {
            $this->setTitle($title);
        }

        // 初始化 content
        $content = $msg['content'] ?? '';
        if (! empty($content)) {
            $this->setContent($content);
        }

        // 初始化 from
        $from = $msg['from'] ?? '';
        if (empty($from) && $setDefault) {
            $this->createDefaultFrom();
        } else {
            $this->setFrom($from);
        }

        // 初始化 to
        $to = $msg['to'] ?? '';
        if (! empty($to)) {
            $this->setTo($to);
        }

        // 初始化 publishTime
        $publishTime = $msg['publishTime'] ?? '';
        if (empty($publishTime) && $setDefault) {
            $this->createDefaultPublishTime();
        } else {
            $this->setPublishTime($publishTime);
        }

        // 初始化 consumeTime
        $consumeTime = $msg['consumeTime'] ?? '';
        if (empty($consumeTime) && $setDefault) {
            $this->createDefaultConsumeTime();
        } else {
            $this->setConsumeTime($consumeTime);
        }

        // 初始化 consumeLog
        $consumeLog = $msg['consumeLog'] ?? [];
        if (! empty($consumeLog)) {
            $this->setConsumeLog($consumeLog);
        }

        // 初始化 errorMsg
        $errorMsg = $msg['errorMsg'] ?? [];
        if (! empty($errorMsg)) {
            $this->setErrorMsg($errorMsg);
        }

        // 初始化 version
        $version = $msg['version'] ?? [];
        if (! empty($version)) {
            $this->setVersion($version);
        }

        return $this;
    }

    /**
     * 获取完整的 MQ 消息
     * @return mixed
     */
    public function getMessage ()
    {
        return new AMQPMessage($this->toString(),
            ['content_type' => 'text/plain',
                'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
    }

}
